#include "znx_spinlock.h"

void
znx_spinlock_lock(znx_spinlock_t *lock)
{
    int64_t i = 0;
    for ( ;; ) {
        if (znx_atomic_int64_cas(lock, 0, 1)) {
            return;
        }

        i++;
        if (i > ZNX_LOCK_SPIN) {
            ZNX_SCHED_YIELD;
        }
    }
}


znx_bool_t
znx_spinlock_trylock(znx_spinlock_t *lock) {
    int64_t i = 0;
    for ( ;; ) {
        if (znx_atomic_int64_cas(lock, 0, 1)) {
            return ZNX_TRUE;
        }

        i++;
        if (i > ZNX_LOCK_SPIN) {
            return ZNX_FALSE;
        }
    }
}


void
znx_spin_wait_group_wait(znx_spin_wait_group_t *wait_group)
{
    int64_t status;
    int64_t i = 0;
    for ( ;; ) {
        status = znx_atomic_int64_load(wait_group);
        if (status == 0) {
            return;
        }

        if (status < 0) {
            ZNX_ASSERT_FATAL("unexcept status");
        }

        i++;
        if (i > ZNX_LOCK_SPIN) {
            ZNX_SCHED_YIELD;
        }
    }
}
